# Упражнения: Функции

1. Реализуйте функцию `random(min, max)`, возвращающую псевдо-случайное
значение от `min` до `max`. Используйте `Math.random()` и `Math.floor()`.
При вызове `random(max)` нужно считать, что `min = 0`.
2. Реализуйте функцию `generateKey(length, characters)`, возвращающую строку
случайных символов из набора `characters` длиной `length`. Например:
```js
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
const key = generateKey(16, characters);
console.log(key); // eg599gb60q926j8i
```
3. Преобразуйте IP адрес (IPv4) в число, содержащее 4 байта адреса,
сдвинутые битовым сдвигом, по такой схеме:
- 1 байт сдвинут 3 раза на 8 бит влево
- 2 байт сдвинут 2 раза на 8 бит влево
- 3 байт сдвинут 1 раз на 8 бит влево
- 1 байт не сдвинут
Например: '10.0.0.1':
- Преобразовываем строку `'10.0.0.1'` в массив `['10', '0', '0', '1']`
- Преобразовываем массив `['10', '0', '0', '1']` в массив `[10, 0, 0, 1]`
- Сдвигаем все элементы по приведенной схеме при помощи цикла:
`[10 << 8 << 8 << 8, 0 << 8 << 8, 0 << 8, 1]` и получаем `[167772160, 0, 0, 1]`
- Суммируем все элементы и получаем `167772161`
- Оптимизируем код через использование `Array.prototype.reduce`
Используйте значение аргумента функции по умолчанию '127.0.0.1'.

Еще примеры:
```
127.0.0.1       ->  2130706433
10.0.0.1        ->   167772161
192.168.1.10    -> -1062731510
165.225.133.150 -> -1511946858
0.0.0.0         ->           0
8.8.8.8         ->  0x08080808
```
4. Реализуйте интроспекцию объекта:
- Проитерируйте все ключи объекта `iface`
- Возьмите ключи функционального типа
- Для каждой функции возьмите количество аргументов
- Сохраните результаты в двумерный массив

Например, из:
```js
{
  m1: x => [x],
  m2: function (x, y) {
    return [x, y];
  },
  m3(x, y, z) {
    return [x, y, z];
  }
}
```
нужно получить:
```js
[
  ['m1', 1],
  ['m2', 2],
  ['m3', 3]
]
```
